import * as echarts from 'echarts'
import { merge } from 'lodash'

const fontSize = 16
// 文字颜色
const textColor = '#333333'
const valueColor = '#666666'

const initLegend = (data: any[]) => {
  return {
    type: 'scroll',
    icon: 'circle',
    itemGap: 14,
    formatter(name: string) {
      const itemInfor = data.find((item) => item.name === name)
      let showName = name
      if (showName.length > 4) {
        showName = `${showName.substring(0, 4)}...`
      }
      return `{name|${showName}}  {value|${itemInfor.value}${itemInfor.unit}}`
    },
    textStyle: {
      color: valueColor,
      rich: {
        name: {
          fontSize,
          width: 120,
          color: textColor
        },
        value: {
          fontSize,
          color: valueColor
        }
      }
    }
  }
}
const initTooltip = () => ({
  trigger: 'item',
  formatter: '{d}%',
  textStyle: {
    color: textColor,
    fontSize
  }
})

const initSeries = (series = [{}]) => {
  let seriesItem = {}
  const initSeriesOption = {
    type: 'pie',
    radius: ['50%', '70%'],
    center: ['50%', '50%'],
    startAngle: 90, // 起始角度
    clockwise: true, // 饼图的扇区是否是顺时针排布
    legendHoverLink: false,
    itemStyle: {
      borderWidth: 0,
      borderColor: '#ffffff'
    },
    label: {
      show: false,
      position: 'center',
      formatter(params: any) {
        return `{value|${params.value}}{unit|${params.data.unit || ''}\n}{name|${params.name}}`
      },
      rich: {
        name: {
          color: textColor,
          fontSize: 14
        },
        value: {
          color: valueColor,
          fontSize: 22,
          padding: [8, 0, 0, 0],
          fontWeight: 700
        },
        unit: {
          fontSize: 12,
          color: valueColor,
          padding: [14, 0, 0, 4]
        }
      }
    },
    emphasis: {
      label: {
        show: true
      }
    },
    labelLine: {
      show: false
    }
  }
  seriesItem = merge({}, initSeriesOption, series[0])
  return [seriesItem]
}

interface chartProps {
  dom: string
  tooltip?: object
  legend?: object
  series: any[]
  data?: any[]
  color?: string[]
  highlightEvent?: (params: any) => void
  speed?: number
  clickEvent?: (params: any) => void
}

export default class HSGlobalPieChart {
  public myChart: any
  public option: any
  public autoSetInterval: any
  public clickEvent?: (params: any) => void
  public highlightEvent: (params: any) => void
  #series: any[]
  #currentItem: any
  #currentIndex: number
  #speed: number
  #legendSelected: any

  // highlightEvent: 鼠标移入高亮的回调事件
  // speed: 自动轮播速度
  // clickEvent: 点击事件回调
  // data = [{name: "化学药", value: 18}, {name: "体外诊断", value: 12}]
  constructor({ dom, tooltip, legend, series, color = [], highlightEvent, speed, clickEvent, ...rest }: chartProps) {
    // 销毁重新绘制
    if (document.getElementById(dom)) {
      document.getElementById(dom)?.removeAttribute('_echarts_instance_')
    }
    // 浮框
    const mergeLegend = merge({}, initLegend(series[0].data), legend)
    const mergeTooltip = merge({}, initTooltip, tooltip)
    this.#series = initSeries(series)
    this.myChart = null
    this.clickEvent = clickEvent
    this.option = {}
    this.highlightEvent =
      highlightEvent ||
      (() => {
        //
      })
    this.#currentItem = {}
    this.#currentIndex = -1
    this.autoSetInterval = null
    this.#speed = speed || 3000
    this.#legendSelected = null
    this.initChart(dom, color, mergeTooltip, mergeLegend, rest)
  }

  initChart(dom: string, color: string[], tooltip: any, legend: any, rest: any) {
    // 基于准备好的dom，初始化echarts实例
    this.myChart = echarts.init(document.getElementById(dom) as HTMLElement)
    this.myChart.off('mouseover')
    this.myChart.off('mouseout')
    this.myChart.off('click')
    // 绘制图表
    this.option = {
      tooltip,
      legend,
      series: this.#series,
      color: color?.length
        ? color
        : [
            '#46A0FF',
            '#FFC64C',
            '#63E587',
            '#FA885D',
            '#7BF0EB',
            '#F277E1',
            '#FF7B7B',
            '#728EFE',
            '#E1EC9E',
            '#8F2EFF',
            '#8DEEFF',
            '#7C69F2',
            '#CCF6B5',
            '#EE8989',
            '#84B2FF',
            '#80E5C4'
          ],
      ...rest
    }
    this.myChart.setOption(this.option)
    this.autoLoop()
    this.pieEvent()
    window.addEventListener('resize', () => this.myChart.resize(), false)
  }

  pieEvent() {
    // pie实例化
    this.myChart.on('mouseover', (params: any) => {
      clearInterval(this.autoSetInterval)
      if (params.dataIndex !== this.#currentIndex) {
        this.myChart.dispatchAction({
          type: 'downplay',
          dataIndex: this.#currentIndex
        })
      }
      this.#currentItem = params || {}
      this.highlightEvent(this.#currentItem)
    })

    this.myChart.on('mouseout', () => {
      clearInterval(this.autoSetInterval)
      this.autoLoop()
    })

    this.myChart.on('click', (params: any) => {
      if (this.clickEvent) {
        this.clickEvent(params)
      }
    })

    this.myChart.on('legendselectchanged', (params: any) => {
      this.#legendSelected = params.selected
      this.autoLoop()
    })
  }

  autoLoop() {
    this.autoHighligth()
    clearInterval(this.autoSetInterval)
    let selectedLen = this.#series[0].data.length
    if (this.#legendSelected) {
      const selectedList = Object.keys(this.#legendSelected).filter((key) => this.#legendSelected[key])
      selectedLen = selectedList.length
    }
    if (selectedLen > 1) {
      this.autoSetInterval = setInterval(this.autoHighligth.bind(this), this.#speed)
    }
  }

  autoHighligth() {
    // 取消之前高亮的图形
    this.myChart.dispatchAction({
      type: 'downplay',
      dataIndex: this.#currentIndex
    })
    this.checkHighlight()
    this.highlightEvent(this.#currentItem)
    // 高亮当前图形
    this.myChart.dispatchAction({
      type: 'highlight',
      dataIndex: this.#currentIndex
    })
  }

  checkHighlight() {
    const { data } = this.#series[0]
    const dataLen = data.length
    if (!dataLen) {
      return
    }
    this.#currentIndex = (this.#currentIndex + 1) % dataLen
    this.#currentItem = data[this.#currentIndex] || {}

    while (this.#legendSelected && !this.#legendSelected[this.#currentItem.name] && Object.values(this.#legendSelected).some((m) => m === true)) {
      this.#currentIndex = (this.#currentIndex + 1) % dataLen
      this.#currentItem = data[this.#currentIndex] || {}
    }
  }
}
